<!DOCTYPE html>
<html class="client-nojs vector-feature-night-mode-disabled vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-sticky-header-enabled" lang="en" dir="ltr"><head>
<meta charset="UTF-8">
<title>Virtual method table</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="https://en.wikipedia.org/wiki/Virtual_method_table"> <link href="./mw/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/user.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" type="text/css" href="./mw/site.styles.css">
<link rel="stylesheet" type="text/css" href="./mw/noscript.css">
<link rel="stylesheet" type="text/css" href="./footer.css">
<link rel="stylesheet" type="text/css" href="./vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Virtual_method_table rootpage-Virtual_method_table skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading">
<span id="openzim-page-title" class="mw-page-title-main"><span class="mw-page-title-main">Virtual method table</span></span>
</h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="en" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="en" dir="ltr">
<style data-mw-deduplicate="TemplateStyles:r1236090951">
/* start https://en.wikipedia.org/ */
.mw-parser-output .hatnote{font-style:italic}.mw-parser-output div.hatnote{padding-left:1.6em;margin-bottom:0.5em}.mw-parser-output .hatnote i{font-style:normal}.mw-parser-output .hatnote+link+.hatnote{margin-top:-0.5em}@media print{body.ns-0 .mw-parser-output .hatnote{display:none!important}}
/* end https://en.wikipedia.org/ */
</style><div role="note" class="hatnote navigation-not-searchable">"Virtual table" redirects here. For virtual tables in SQL, see <a href="View_(SQL)" title="View (SQL)">View (SQL)</a>.</div>
<p class="mw-empty-elt">
</p><p>In <a href="Computer_programming" title="Computer programming">computer programming</a>, a <b>virtual method table</b> (<b>VMT</b>), <b>virtual function table</b>, <b>virtual call table</b>, <a href="Dispatch_table" title="Dispatch table">dispatch table</a>, <b>vtable</b>, or <b>vftable</b> is a mechanism used in a <a href="Programming_language" title="Programming language">programming language</a> to support <a href="Dynamic_dispatch" title="Dynamic dispatch">dynamic dispatch</a> (or <a href="Run_time_(program_lifecycle_phase)" class="mw-redirect" title="Run time (program lifecycle phase)">run-time</a> method <a href="Name_binding" title="Name binding">binding</a>).
</p><p>Whenever a <a href="Class_(computer_programming)" title="Class (computer programming)">class</a> defines a <a href="Virtual_function" title="Virtual function">virtual function</a> (or <a href="Method_(computer_programming)" title="Method (computer programming)">method</a>), most <a href="Compiler" title="Compiler">compilers</a> add a hidden <a href="Member_variable" title="Member variable">member variable</a> to the class that points to an array of <a href="Pointer_(computer_programming)" title="Pointer (computer programming)">pointers</a> to (virtual) functions called the virtual method table. These pointers are used at runtime to invoke the appropriate function implementations, because at compile time it may not yet be known if the base function is to be called or a derived one implemented by a class that <a href="Inheritance_(object-oriented_programming)" title="Inheritance (object-oriented programming)">inherits</a> from the base class.
</p><p>There are many different ways to implement such dynamic dispatch, but use of virtual method tables is especially common among <a href="C%2B%2B" title="C++">C++</a> and related languages (such as <a href="D_(programming_language)" title="D (programming language)">D</a> and <a href="C_Sharp_(programming_language)" title="C Sharp (programming language)">C#</a>). Languages that separate the programmatic interface of objects from the implementation, like <a href="Visual_Basic" title="Visual Basic">Visual Basic</a> and <a href="Delphi_(programming_language)" class="mw-redirect" title="Delphi (programming language)">Delphi</a>, also tend to use this approach, because it allows objects to use a different implementation simply by using a different set of method pointers. The method allows creation of external libraries, where other techniques perhaps may not.<sup id="cite_ref-inria-00565627_1-0" class="reference"><a href="#cite_note-inria-00565627-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup>
</p><p>Suppose a program contains three classes in an inheritance hierarchy: a <a href="Superclass_(computer_science)" class="mw-redirect" title="Superclass (computer science)">superclass</a>, <style data-mw-deduplicate="TemplateStyles:r886049734">
/* start https://en.wikipedia.org/ */
.mw-parser-output .monospaced{font-family:monospace,monospace}
/* end https://en.wikipedia.org/ */
</style><span class="monospaced">Cat</span>, and two <a href="Subclass_(computer_science)" class="mw-redirect" title="Subclass (computer science)">subclasses</a>, <span class="monospaced">HouseCat</span> and <span class="monospaced">Lion</span>. Class <span class="monospaced">Cat</span> defines a <a href="Virtual_function" title="Virtual function">virtual function</a> named <span class="monospaced">speak</span>, so its subclasses may provide an appropriate implementation (e.g. either <span class="monospaced">meow</span> or <span class="monospaced">roar</span>). When the program calls the <span class="monospaced">speak</span> function on a <span class="monospaced">Cat</span> reference (which can refer to an instance of <span class="monospaced">Cat</span>, or an instance of <span class="monospaced">HouseCat</span> or <span class="monospaced">Lion</span>), the code must be able to determine which implementation of the function the call should be <i>dispatched</i> to. This depends on the actual class of the object, not the class of the reference to it (<span class="monospaced">Cat</span>). The class cannot generally be determined <i>statically</i> (that is, at <a href="Compile_time" title="Compile time">compile time</a>), so neither can the compiler decide which function to call at that time. The call must be dispatched to the right function <i>dynamically</i> (that is, at <a href="Run_time_(program_lifecycle_phase)" class="mw-redirect" title="Run time (program lifecycle phase)">run time</a>) instead.
</p>
<meta property="mw:PageProp/toc">
<div class="mw-heading mw-heading2"><h2 id="Implementation">Implementation</h2></div>
<p>An object's virtual method table will contain the <a href="Memory_address" title="Memory address">addresses</a> of the object's dynamically bound methods. Method calls are performed by fetching the method's address from the object's virtual method table. The virtual method table is the same for all objects belonging to the same class, and is therefore typically shared between them. Objects belonging to type-compatible classes (for example siblings in an inheritance hierarchy) will have virtual method tables with the same layout: the address of a given method will appear at the same offset for all type-compatible classes. Thus, fetching the method's address from a given offset into a virtual method table will get the method corresponding to the object's actual class.<sup id="cite_ref-2" class="reference"><a href="#cite_note-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup>
</p><p>The <a href="C%2B%2B" title="C++">C++</a> standards do not mandate exactly how dynamic dispatch must be implemented, but compilers generally use minor variations on the same basic model.
</p><p>Typically, the compiler creates a separate virtual method table for each class. When an object is created, a pointer to this table, called the <b>virtual table pointer</b>, <b>vpointer</b> or <b>VPTR</b>, is added as a hidden member of this object. As such, the compiler must also generate "hidden" code in the <a href="Constructor_(object-oriented_programming)" title="Constructor (object-oriented programming)">constructors</a> of each class to initialize a new object's virtual table pointer to the address of its class's virtual method table.
</p><p>Many compilers place the virtual table pointer as the last member of the object; other compilers place it as the first; portable source code works either way.<sup id="cite_ref-3" class="reference"><a href="#cite_note-3"><span class="cite-bracket">[</span>3<span class="cite-bracket">]</span></a></sup>
For example, <a href="G%2B%2B" class="mw-redirect" title="G++">g++</a> previously placed the pointer at the end of the object.<sup id="cite_ref-4" class="reference"><a href="#cite_note-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="Example">Example</h2></div>
<p>Consider the following class declarations in <a href="C%2B%2B_syntax" title="C++ syntax">C++ syntax</a>:
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="k">class</span><span class="w"> </span><span class="nc">B1</span><span class="w"> </span><span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
<span class="w"> </span><span class="k">virtual</span><span class="w"> </span><span class="o">~</span><span class="n">B1</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span>
<span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">fnonvirtual</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span>
<span class="w"> </span><span class="k">virtual</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">f1</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">int_in_b1</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">class</span><span class="w"> </span><span class="nc">B2</span><span class="w"> </span><span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
<span class="w"> </span><span class="k">virtual</span><span class="w"> </span><span class="o">~</span><span class="n">B2</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span>
<span class="w"> </span><span class="k">virtual</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">f2</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">int_in_b2</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
<p>used to derive the following class:
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="k">class</span><span class="w"> </span><span class="nc">D</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="n">B1</span><span class="p">,</span><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="n">B2</span><span class="w"> </span><span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
<span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">d</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span>
<span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">f2</span><span class="p">()</span><span class="w"> </span><span class="k">override</span><span class="w"> </span><span class="p">{}</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">int_in_d</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
<p>and the following piece of C++ code:
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="n">B2</span><span class="w"> </span><span class="o">*</span><span class="n">b2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">B2</span><span class="p">();</span>
<span class="n">D</span><span class="w"> </span><span class="o">*</span><span class="n">d</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">D</span><span class="p">();</span>
</pre></div>
<p>g++ 3.4.6 from <a href="GNU_Compiler_Collection" title="GNU Compiler Collection">GCC</a> produces the following 32-bit memory layout for the object <code>b2</code>:<sup id="cite_ref-5" class="reference"><a href="#cite_note-5"><span class="cite-bracket">[</span>nb 1<span class="cite-bracket">]</span></a></sup>
</p>
<pre>b2:
+0: pointer to virtual method table of B2
+4: value of int_in_b2
virtual method table of B2:
+0: B2::f2()
</pre>
<p>and the following memory layout for the object <code>d</code>:
</p>
<pre>d:
+0: pointer to virtual method table of D (for B1)
+4: value of int_in_b1
+8: pointer to virtual method table of D (for B2)
+12: value of int_in_b2
+16: value of int_in_d
Total size: 20 Bytes.
virtual method table of D (for B1):
+0: B1::f1() // B1::f1() is not overridden
virtual method table of D (for B2):
+0: D::f2() // B2::f2() is overridden by D::f2()
// The location of B2::f2 is not in the virtual method table for D
</pre>
<p>Note that those functions not carrying the keyword <code>virtual</code> in their declaration (such as <code>fnonvirtual()</code> and <code>d()</code>) do not generally appear in the virtual method table. There are exceptions for special cases as posed by the <a href="Default_constructor" title="Default constructor">default constructor</a>.
</p><p>Also note the <a href="Virtual_function#Virtual_destructors" title="Virtual function">virtual destructors</a> in the base classes, <code>B1</code> and <code>B2</code>. They are necessary to ensure <code>delete d</code> can free up memory not just for <code>D</code>, but also for <code>B1</code> and <code>B2</code>, if <code>d</code> is a pointer or reference to the types <code>B1</code> or <code>B2</code>. They were excluded from the memory layouts to keep the example simple. <sup id="cite_ref-6" class="reference"><a href="#cite_note-6"><span class="cite-bracket">[</span>nb 2<span class="cite-bracket">]</span></a></sup>
</p><p><a href="Method_overriding" title="Method overriding">Overriding of the method</a> <code>f2()</code> in class <code>D</code> is implemented by duplicating the virtual method table of <code>B2</code> and replacing the pointer to <code>B2::f2()</code> with a pointer to <code>D::f2()</code>.
</p>
<div class="mw-heading mw-heading2"><h2 id="Multiple_inheritance_and_thunks">Multiple inheritance and thunks</h2></div>
<p>The g++ compiler implements the <a href="Multiple_inheritance" title="Multiple inheritance">multiple inheritance</a> of the classes <code>B1</code> and <code>B2</code> in class <code>D</code> using two virtual method tables, one for each base class. (There are other ways to implement multiple inheritance, but this is the most common.) This leads to the necessity for "pointer fixups", also called <a href="Thunk_(programming)" class="mw-redirect" title="Thunk (programming)">thunks</a>, when <a href="Type_conversion" title="Type conversion">casting</a>.
</p><p>Consider the following C++ code:
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="n">D</span><span class="w"> </span><span class="o">*</span><span class="n">d</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">D</span><span class="p">();</span>
<span class="n">B1</span><span class="w"> </span><span class="o">*</span><span class="n">b1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">d</span><span class="p">;</span>
<span class="n">B2</span><span class="w"> </span><span class="o">*</span><span class="n">b2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">d</span><span class="p">;</span>
</pre></div>
<p>While <code>d</code> and <code>b1</code> will point to the same memory location after execution of this code, <code>b2</code> will point to the location <code>d+8</code> (eight bytes beyond the memory location of <code>d</code>). Thus, <code>b2</code> points to the region within <code>d</code> that "looks like" an instance of <code>B2</code>, i.e., has the same memory layout as an instance of <code>B2</code>.
</p>
<div class="mw-heading mw-heading2"><h2 id="Invocation">Invocation</h2></div>
<p>A call to <code>d->f1()</code> is handled by dereferencing <code>d</code>'s <code>D::B1</code> vpointer, looking up the <code>f1</code> entry in the virtual method table, and then dereferencing that pointer to call the code.
</p><p><b>Single inheritance</b>
</p><p>In the case of single inheritance (or in a language with only single inheritance), if the vpointer is always the first element in <code>d</code> (as it is with many compilers), this reduces to the following pseudo-C++:
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="p">(</span><span class="o">*</span><span class="p">((</span><span class="o">*</span><span class="n">d</span><span class="p">)[</span><span class="mi">0</span><span class="p">]))(</span><span class="n">d</span><span class="p">)</span>
</pre></div>
<p>Where <code>*d</code> refers to the virtual method table of <code>D</code> and <code>[0]</code> refers to the first method in the virtual method table. The parameter <code>d</code> becomes the <a href="This_(computer_science)" class="mw-redirect" title="This (computer science)">"<code>this</code>" pointer</a> to the object.
</p><p><b>Multiple inheritance</b>
</p><p>In the more general case, calling <code>B1::f1()</code> or <code>D::f2()</code> is more complicated:
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">d</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="cm">/*pointer to virtual method table of D (for B1)*/</span><span class="p">)[</span><span class="mi">0</span><span class="p">]))(</span><span class="n">d</span><span class="p">)</span><span class="w"> </span><span class="cm">/* Call d->f1() */</span>
<span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">d</span><span class="p">[</span><span class="mi">8</span><span class="p">]</span><span class="cm">/*pointer to virtual method table of D (for B2)*/</span><span class="p">)[</span><span class="mi">0</span><span class="p">]))(</span><span class="n">d</span><span class="o">+</span><span class="mi">8</span><span class="p">)</span><span class="w"> </span><span class="cm">/* Call d->f2() */</span>
</pre></div>
<p>The call to <code>d->f1()</code> passes a <code>B1</code> pointer as a parameter. The call to <code>d->f2()</code> passes a <code>B2</code> pointer as a parameter. This second call requires a fixup to produce the correct pointer. The location of <code>B2::f2</code> is not in the virtual method table for <code>D</code>.
</p><p>By comparison, a call to <code>d->fnonvirtual()</code> is much simpler:
</p>
<div class="mw-highlight mw-highlight-lang-cpp mw-content-ltr" dir="ltr"><pre><span class="p">(</span><span class="o">*</span><span class="n">B1</span><span class="o">::</span><span class="n">fnonvirtual</span><span class="p">)(</span><span class="n">d</span><span class="p">)</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Efficiency">Efficiency</h2></div>
<p>A virtual call requires at least an extra indexed dereference and sometimes a "fixup" addition, compared to a non-virtual call, which is simply a jump to a compiled-in pointer. Therefore, calling virtual functions is inherently slower than calling non-virtual functions. An experiment done in 1996 indicates that approximately 6–13% of execution time is spent simply dispatching to the correct function, though the overhead can be as high as 50%.<sup id="cite_ref-7" class="reference"><a href="#cite_note-7"><span class="cite-bracket">[</span>5<span class="cite-bracket">]</span></a></sup> The cost of virtual functions may not be so high on modern <abbr title="Central Processing Unit">CPU</abbr> architectures due to much larger caches and better <a href="Branch_predictor" title="Branch predictor">branch prediction</a>.
</p><p>Furthermore, in environments where <a href="Just-in-time_compilation" title="Just-in-time compilation">JIT compilation</a> is not in use, virtual function calls usually cannot be <a href="Inline_expansion" title="Inline expansion">inlined</a>. In certain cases it may be possible for the compiler to perform a process known as <b>devirtualization</b> in which, for instance, the lookup and indirect call are replaced with a conditional execution of each inlined body, but such optimizations are not common.
</p><p>To avoid this overhead, compilers usually avoid using virtual method tables whenever the call can be resolved at <a href="Compile_time" title="Compile time">compile time</a>.
</p><p>Thus, the call to <code>f1</code> above may not require a table lookup because the compiler may be able to tell that <code>d</code> can only hold a <code>D</code> at this point, and <code>D</code> does not override <code>f1</code>. Or the compiler (or optimizer) may be able to detect that there are no subclasses of <code>B1</code> anywhere in the program that override <code>f1</code>. The call to <code>B1::f1</code> or <code>B2::f2</code> will probably not require a table lookup because the implementation is specified explicitly (although it does still require the 'this'-pointer fixup).
</p>
<div class="mw-heading mw-heading2"><h2 id="Comparison_with_alternatives">Comparison with alternatives</h2></div>
<p>The virtual method table is generally a good performance trade-off to achieve dynamic dispatch, but there are alternatives, such as binary tree dispatch, with higher performance in some typical cases, but different trade-offs.<sup id="cite_ref-inria-00565627_1-1" class="reference"><a href="#cite_note-inria-00565627-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup><sup id="cite_ref-8" class="reference"><a href="#cite_note-8"><span class="cite-bracket">[</span>6<span class="cite-bracket">]</span></a></sup>
</p><p>However, virtual method tables only allow for <a href="Single_dispatch" class="mw-redirect" title="Single dispatch">single dispatch</a> on the special "this" parameter, in contrast to <a href="Multiple_dispatch" title="Multiple dispatch">multiple dispatch</a> (as in <a href="Common_Lisp_Object_System" title="Common Lisp Object System">CLOS</a>, <a href="Dylan_(programming_language)" title="Dylan (programming language)">Dylan</a>, or <a href="Julia_(programming_language)" title="Julia (programming language)">Julia</a>), where the types of all parameters can be taken into account in dispatching.
</p><p>Virtual method tables also only work if dispatching is constrained to a known set of methods, so they can be placed in a simple array built at compile time, in contrast to <a href="Duck_typing" title="Duck typing">duck typing</a> languages (such as <a href="Smalltalk" title="Smalltalk">Smalltalk</a>, <a href="Python_(programming_language)" title="Python (programming language)">Python</a> or <a href="JavaScript" title="JavaScript">JavaScript</a>).
</p><p>Languages that provide either or both of these features often dispatch by looking up a string in a <a href="Hash_table" title="Hash table">hash table</a>, or some other equivalent method. There are a variety of techniques to make this faster (e.g., <a href="String_interning" title="String interning">interning</a>/tokenizing method names, caching lookups, <a href="Just-in-time_compilation" title="Just-in-time compilation">just-in-time compilation</a>).
</p>
<div class="mw-heading mw-heading2"><h2 id="See_also">See also</h2></div>
<ul><li><a href="Virtual_function" title="Virtual function">Virtual function</a></li>
<li><a href="Virtual_inheritance" title="Virtual inheritance">Virtual inheritance</a></li>
<li><a href="Branch_table" title="Branch table">Branch table</a></li></ul>
<div class="mw-heading mw-heading2"><h2 id="Notes">Notes</h2></div>
<div class="mw-references-wrap"><ol class="references">
<li id="cite_note-5"><span class="mw-cite-backlink"><b><a href="#cite_ref-5">^</a></b></span> <span class="reference-text">G++'s <code>-fdump-class-hierarchy</code> (starting with version 8: <code>-fdump-lang-class</code>) argument can be used to dump virtual method tables for manual inspection. For AIX VisualAge XlC compiler, use <code>-qdump_class_hierarchy</code> to dump class hierarchy and virtual function table layout.</span>
</li>
<li id="cite_note-6"><span class="mw-cite-backlink"><b><a href="#cite_ref-6">^</a></b></span> <span class="reference-text"><style data-mw-deduplicate="TemplateStyles:r1238218222">
/* start https://en.wikipedia.org/ */
.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}.mw-parser-output .citation q{quotes:"\"""\"""'""'"}.mw-parser-output .citation:target{background-color:rgba(0,127,255,0.133)}.mw-parser-output .id-lock-free.id-lock-free a{background:url("./mw/Lock-green.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-limited.id-lock-limited a,.mw-parser-output .id-lock-registration.id-lock-registration a{background:url("./mw/Lock-gray-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-subscription.id-lock-subscription a{background:url("./mw/Lock-red-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .cs1-ws-icon a{background:url("./mw/Wikisource-logo.svg")right 0.1em center/12px no-repeat}body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-free a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-limited a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-registration a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-subscription a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .cs1-ws-icon a{background-size:contain;padding:0 1em 0 0}.mw-parser-output .cs1-code{color:inherit;background:inherit;border:none;padding:inherit}.mw-parser-output .cs1-hidden-error{display:none;color:var(--color-error,#d33)}.mw-parser-output .cs1-visible-error{color:var(--color-error,#d33)}.mw-parser-output .cs1-maint{display:none;color:#085;margin-left:0.3em}.mw-parser-output .cs1-kern-left{padding-left:0.2em}.mw-parser-output .cs1-kern-right{padding-right:0.2em}.mw-parser-output .citation .mw-selflink{font-weight:inherit}@media screen{.mw-parser-output .cs1-format{font-size:95%}html.skin-theme-clientpref-night .mw-parser-output .cs1-maint{color:#18911f}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .cs1-maint{color:#18911f}}
/* end https://en.wikipedia.org/ */
</style><cite class="citation web cs1"><a rel="nofollow" class="external text" href="https://stackoverflow.com/questions/17960917/why-there-are-two-virtual-destructor-in-the-virtual-table-and-where-is-address-o">"C++ - why there are two virtual destructor in the virtual table and where is address of the non-virtual function (gcc4.6.3)"</a>.</cite></span>
</li>
</ol></div>
<div class="mw-heading mw-heading2"><h2 id="References">References</h2></div>
<ul><li>Margaret A. Ellis and <a href="Bjarne_Stroustrup" title="Bjarne Stroustrup">Bjarne Stroustrup</a> (1990) The Annotated C++ Reference Manual. Reading, MA: Addison-Wesley. (<a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a> <bdi>0-201-51459-1</bdi>)</li></ul>
<style data-mw-deduplicate="TemplateStyles:r1239543626">
/* start https://en.wikipedia.org/ */
.mw-parser-output .reflist{margin-bottom:0.5em;list-style-type:decimal}@media screen{.mw-parser-output .reflist{font-size:90%}}.mw-parser-output .reflist .references{font-size:100%;margin-bottom:0;list-style-type:inherit}.mw-parser-output .reflist-columns-2{column-width:30em}.mw-parser-output .reflist-columns-3{column-width:25em}.mw-parser-output .reflist-columns{margin-top:0.3em}.mw-parser-output .reflist-columns ol{margin-top:0}.mw-parser-output .reflist-columns li{page-break-inside:avoid;break-inside:avoid-column}.mw-parser-output .reflist-upper-alpha{list-style-type:upper-alpha}.mw-parser-output .reflist-upper-roman{list-style-type:upper-roman}.mw-parser-output .reflist-lower-alpha{list-style-type:lower-alpha}.mw-parser-output .reflist-lower-greek{list-style-type:lower-greek}.mw-parser-output .reflist-lower-roman{list-style-type:lower-roman}
/* end https://en.wikipedia.org/ */
</style><div class="reflist">
<div class="mw-references-wrap"><ol class="references">
<li id="cite_note-inria-00565627-1"><span class="mw-cite-backlink">^ <a href="#cite_ref-inria-00565627_1-0"><sup><i><b>a</b></i></sup></a> <a href="#cite_ref-inria-00565627_1-1"><sup><i><b>b</b></i></sup></a></span> <span class="reference-text"><cite id="CITEREFZendraColnetCollin1997" class="citation book cs1">Zendra, Olivier; Colnet, Dominique; Collin, Suzanne (1997). <a rel="nofollow" class="external text" href="https://hal.inria.fr/inria-00565627/document"><i>Efficient Dynamic Dispatch without Virtual Function Tables: The SmallEiffel Compiler -- 12th Annual ACM SIGPLAN Conference on Object-Oriented Programming Systems, Languages and Applications (OOPSLA'97), ACM SIGPLAN, Oct 1997, Atlanta, United States. pp.125-141. inria-00565627</i></a>. Centre de Recherche en Informatique de Nancy Campus Scientifique, Bâtiment LORIA. p. 16.</cite></span>
</li>
<li id="cite_note-2"><span class="mw-cite-backlink"><b><a href="#cite_ref-2">^</a></b></span> <span class="reference-text">Ellis & Stroustrup 1990, pp. 227–232</span>
</li>
<li id="cite_note-3"><span class="mw-cite-backlink"><b><a href="#cite_ref-3">^</a></b></span> <span class="reference-text">
Danny Kalev.
<a rel="nofollow" class="external text" href="http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=196">"C++ Reference Guide: The Object Model II"</a>.
2003.
Heading "Inheritance and Polymorphism" and "Multiple Inheritance".</span>
</li>
<li id="cite_note-4"><span class="mw-cite-backlink"><b><a href="#cite_ref-4">^</a></b></span> <span class="reference-text"><cite class="citation web cs1"><a rel="nofollow" class="external text" href="https://web.archive.org/web/20110725153606/http://www.codesourcery.com/public/cxx-abi/cxx-closed.html">"C++ ABI Closed Issues"</a>. Archived from the original on 25 July 2011<span class="reference-accessdate">. Retrieved <span class="nowrap">17 June</span> 2011</span>.</cite><span class="cs1-maint citation-comment"><code class="cs1-code">{{cite web}}</code>: CS1 maint: bot: original URL status unknown (link)</span></span>
</li>
<li id="cite_note-7"><span class="mw-cite-backlink"><b><a href="#cite_ref-7">^</a></b></span> <span class="reference-text">Driesen, Karel and Hölzle, Urs, <a rel="nofollow" class="external text" href="https://dl.acm.org/doi/10.1145/236338.236369">"The Direct Cost of Virtual Function Calls in C++"</a>, OOPSLA 1996</span>
</li>
<li id="cite_note-8"><span class="mw-cite-backlink"><b><a href="#cite_ref-8">^</a></b></span> <span class="reference-text">Zendra, Olivier and Driesen, Karel, <a rel="nofollow" class="external text" href="http://www.usenix.org/event/jvm02/full_papers/zendra/zendra_html/index.html">"Stress-testing Control Structures for Dynamic Dispatch in Java"</a>, pp. 105–118, Proceedings of the USENIX 2nd Java Virtual Machine Research and Technology Symposium, 2002 (JVM '02)</span>
</li>
</ol></div></div>
<div class="navbox-styles"><style data-mw-deduplicate="TemplateStyles:r1129693374">
/* start https://en.wikipedia.org/ */
.mw-parser-output .hlist dl,.mw-parser-output .hlist ol,.mw-parser-output .hlist ul{margin:0;padding:0}.mw-parser-output .hlist dd,.mw-parser-output .hlist dt,.mw-parser-output .hlist li{margin:0;display:inline}.mw-parser-output .hlist.inline,.mw-parser-output .hlist.inline dl,.mw-parser-output .hlist.inline ol,.mw-parser-output .hlist.inline ul,.mw-parser-output .hlist dl dl,.mw-parser-output .hlist dl ol,.mw-parser-output .hlist dl ul,.mw-parser-output .hlist ol dl,.mw-parser-output .hlist ol ol,.mw-parser-output .hlist ol ul,.mw-parser-output .hlist ul dl,.mw-parser-output .hlist ul ol,.mw-parser-output .hlist ul ul{display:inline}.mw-parser-output .hlist .mw-empty-li{display:none}.mw-parser-output .hlist dt::after{content:": "}.mw-parser-output .hlist dd::after,.mw-parser-output .hlist li::after{content:" · ";font-weight:bold}.mw-parser-output .hlist dd:last-child::after,.mw-parser-output .hlist dt:last-child::after,.mw-parser-output .hlist li:last-child::after{content:none}.mw-parser-output .hlist dd dd:first-child::before,.mw-parser-output .hlist dd dt:first-child::before,.mw-parser-output .hlist dd li:first-child::before,.mw-parser-output .hlist dt dd:first-child::before,.mw-parser-output .hlist dt dt:first-child::before,.mw-parser-output .hlist dt li:first-child::before,.mw-parser-output .hlist li dd:first-child::before,.mw-parser-output .hlist li dt:first-child::before,.mw-parser-output .hlist li li:first-child::before{content:" (";font-weight:normal}.mw-parser-output .hlist dd dd:last-child::after,.mw-parser-output .hlist dd dt:last-child::after,.mw-parser-output .hlist dd li:last-child::after,.mw-parser-output .hlist dt dd:last-child::after,.mw-parser-output .hlist dt dt:last-child::after,.mw-parser-output .hlist dt li:last-child::after,.mw-parser-output .hlist li dd:last-child::after,.mw-parser-output .hlist li dt:last-child::after,.mw-parser-output .hlist li li:last-child::after{content:")";font-weight:normal}.mw-parser-output .hlist ol{counter-reset:listitem}.mw-parser-output .hlist ol>li{counter-increment:listitem}.mw-parser-output .hlist ol>li::before{content:" "counter(listitem)"\a0 "}.mw-parser-output .hlist dd ol>li:first-child::before,.mw-parser-output .hlist dt ol>li:first-child::before,.mw-parser-output .hlist li ol>li:first-child::before{content:" ("counter(listitem)"\a0 "}
/* end https://en.wikipedia.org/ */
</style><style data-mw-deduplicate="TemplateStyles:r1236075235">
/* start https://en.wikipedia.org/ */
.mw-parser-output .navbox{box-sizing:border-box;border:1px solid #a2a9b1;width:100%;clear:both;font-size:88%;text-align:center;padding:1px;margin:1em auto 0}.mw-parser-output .navbox .navbox{margin-top:0}.mw-parser-output .navbox+.navbox,.mw-parser-output .navbox+.navbox-styles+.navbox{margin-top:-1px}.mw-parser-output .navbox-inner,.mw-parser-output .navbox-subgroup{width:100%}.mw-parser-output .navbox-group,.mw-parser-output .navbox-title,.mw-parser-output .navbox-abovebelow{padding:0.25em 1em;line-height:1.5em;text-align:center}.mw-parser-output .navbox-group{white-space:nowrap;text-align:right}.mw-parser-output .navbox,.mw-parser-output .navbox-subgroup{background-color:#fdfdfd}.mw-parser-output .navbox-list{line-height:1.5em;border-color:#fdfdfd}.mw-parser-output .navbox-list-with-group{text-align:left;border-left-width:2px;border-left-style:solid}.mw-parser-output tr+tr>.navbox-abovebelow,.mw-parser-output tr+tr>.navbox-group,.mw-parser-output tr+tr>.navbox-image,.mw-parser-output tr+tr>.navbox-list{border-top:2px solid #fdfdfd}.mw-parser-output .navbox-title{background-color:#ccf}.mw-parser-output .navbox-abovebelow,.mw-parser-output .navbox-group,.mw-parser-output .navbox-subgroup .navbox-title{background-color:#ddf}.mw-parser-output .navbox-subgroup .navbox-group,.mw-parser-output .navbox-subgroup .navbox-abovebelow{background-color:#e6e6ff}.mw-parser-output .navbox-even{background-color:#f7f7f7}.mw-parser-output .navbox-odd{background-color:transparent}.mw-parser-output .navbox .hlist td dl,.mw-parser-output .navbox .hlist td ol,.mw-parser-output .navbox .hlist td ul,.mw-parser-output .navbox td.hlist dl,.mw-parser-output .navbox td.hlist ol,.mw-parser-output .navbox td.hlist ul{padding:0.125em 0}.mw-parser-output .navbox .navbar{display:block;font-size:100%}.mw-parser-output .navbox-title .navbar{float:left;text-align:left;margin-right:0.5em}body.skin--responsive .mw-parser-output .navbox-image img{max-width:none!important}@media print{body.ns-0 .mw-parser-output .navbox{display:none!important}}
/* end https://en.wikipedia.org/ */
</style></div><div role="navigation" class="navbox" aria-labelledby="Application_binary_interface_(ABI)74" style="padding:3px"><table class="nowraplinks mw-collapsible autocollapse navbox-inner" style="border-spacing:0;background:transparent;color:inherit"><tbody><tr><th scope="col" class="navbox-title" colspan="2"><style data-mw-deduplicate="TemplateStyles:r1239400231">
/* start https://en.wikipedia.org/ */
.mw-parser-output .navbar{display:inline;font-size:88%;font-weight:normal}.mw-parser-output .navbar-collapse{float:left;text-align:left}.mw-parser-output .navbar-boxtext{word-spacing:0}.mw-parser-output .navbar ul{display:inline-block;white-space:nowrap;line-height:inherit}.mw-parser-output .navbar-brackets::before{margin-right:-0.125em;content:"[ "}.mw-parser-output .navbar-brackets::after{margin-left:-0.125em;content:" ]"}.mw-parser-output .navbar li{word-spacing:-0.125em}.mw-parser-output .navbar a>span,.mw-parser-output .navbar a>abbr{text-decoration:inherit}.mw-parser-output .navbar-mini abbr{font-variant:small-caps;border-bottom:none;text-decoration:none;cursor:inherit}.mw-parser-output .navbar-ct-full{font-size:114%;margin:0 7em}.mw-parser-output .navbar-ct-mini{font-size:114%;margin:0 4em}html.skin-theme-clientpref-night .mw-parser-output .navbar li a abbr{color:var(--color-base)!important}@media(prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .navbar li a abbr{color:var(--color-base)!important}}@media print{.mw-parser-output .navbar{display:none!important}}
/* end https://en.wikipedia.org/ */
</style><div id="Application_binary_interface_(ABI)74" style="font-size:114%;margin:0 4em"><a href="Application_binary_interface" title="Application binary interface">Application binary interface</a> (ABI)</div></th></tr><tr><th scope="row" class="navbox-group" style="width:1%">Parts,<br>conventions</th><td class="navbox-list-with-group navbox-list navbox-odd hlist" style="width:100%;padding:0"><div style="padding:0 0.25em">
<ul><li><a href="Data_structure_alignment" title="Data structure alignment">Alignment</a></li>
<li><a href="Calling_convention" title="Calling convention">Calling convention</a></li>
<li><a href="Call_stack" title="Call stack">Call stack</a></li>
<li><a href="Library_(computing)" title="Library (computing)">Library</a>
<ul><li><a href="Static_library" title="Static library">static</a></li></ul></li>
<li><a href="Machine_code" title="Machine code">Machine code</a></li>
<li><a href="Memory_segmentation" title="Memory segmentation">Memory segmentation</a></li>
<li><a href="Name_mangling" title="Name mangling">Name mangling</a></li>
<li><a href="Object_code" title="Object code">Object code</a></li>
<li><a href="Opaque_pointer" title="Opaque pointer">Opaque pointer</a></li>
<li><a href="Position-independent_code" title="Position-independent code">Position-independent code</a></li>
<li><a href="Relocation_(computing)" title="Relocation (computing)">Relocation</a></li>
<li><a href="System_call" title="System call">System call</a></li>
</ul>
</div></td></tr><tr><th scope="row" class="navbox-group" style="width:1%">Related topics</th><td class="navbox-list-with-group navbox-list navbox-even hlist" style="width:100%;padding:0"><div style="padding:0 0.25em">
<ul><li><a href="Binary-code_compatibility" title="Binary-code compatibility">Binary-code compatibility</a></li>
<li><a href="Foreign_function_interface" title="Foreign function interface">Foreign function interface</a></li>
<li><a href="Language_binding" title="Language binding">Language binding</a></li>
<li><a href="Linker_(computing)" title="Linker (computing)">Linker</a>
<ul><li><a href="Dynamic_linker" title="Dynamic linker">dynamic</a></li></ul></li>
<li><a href="Loader_(computing)" title="Loader (computing)">Loader</a></li>
<li><a href="Year_2038_problem" title="Year 2038 problem">Year 2038 problem</a></li></ul>
</div></td></tr></tbody></table></div></div><!--htdig_noindex--><div><div class="zim-footer">
This article is issued from <a class="external text" title="Last edited on 2024-04-23" href="https://en.wikipedia.org/wiki/?title=Virtual_method_table&oldid=1220366429">Wikipedia</a>. The text is available under <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">Creative Commons Attribution-Share Alike 4.0</a> unless otherwise noted. Additional terms may apply for the media files.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
</body></html>